"""
1. 如何为函数定义keyword-only参数（写出个例子即可）？

keyword-only意思是只允许关键字传参

*args之后出现的普通参数就是keyword-only参数

"""


def fn(*args, x, y, **kwargs):
    print(x, y, args, kwargs, sep='    ')
    print("*" * 10)


fn(3, 5, x=3, y=4)  # 3    4    (3, 5)    {}
fn(3, 5, x=1, y=2, a=1, b='abc')  # 1    2    (3, 5)    {'a': 1, 'b': 'abc'}

"""
2. 什么是LEGB，请解释

LEGB是变量解析的原则
是解析顺序的首字母
Local，本地作用域、局部作用域的local命名空间。函数调用时创建，调用结束消亡
Enclosing，Python2.2时引入了嵌套函数，实现了闭包，这个就是嵌套函数的外部函数的命名空间
Global，全局作用域，即一个模块的命名空间。模块被import时创建，解释器退出时消亡
Build-in，内置模块的命名空间，生命周期从python解释器启动时创建到解释器退出时消亡。

解析顺序就是
本地--->模块--->全局--->内置
"""

"""
使用本周学习的技术改造第一周的计算器实现，其目标如下：
   1. 运行后提示让用户输入一个数字
   2. 提示输入操作符（+ - * /）
   3. 再次提示输入一个数字
   4. 打印计算结果
   5. 在不退出程序的前提下，可以允许用户继续输入新一组数据计
   6. 尽可能改善用户体验（新需求）
"""

"""
下面的计算器可以输入整数，小数，计算加减乘除
也可以直接输入两项的计算表达式直接计算结果
输出结果如果为小数的话，默认两位小数
"""
def check_num(l):
    for i in l:
        if not i.strip("-").isnumeric():
            if i.startswith("."):
                i = "0" + i
            li = i.strip(".").split(".")
            if len(li) !=2 or not check_num(li):
                return False
    return True


def into(msg, t):
    while 1:
        In = input(msg).strip()
        if In == "":
            print("不能为空")
            continue
        if In == "q":
            exit()
        if t == "num":
            tmp = In.strip("+").strip("-").strip("*").strip("/")
            if tmp.count("+") == 0 and tmp.count("-") == 0 and tmp.count("*") == 0 and tmp.count("/") == 0:
                zf = False
                if In.startswith("."):
                    In = "0" + In
                if In.startswith("-"):
                    zf = True
                    In = In.lstrip("-")
                li = In.strip(".").split(".")
                if len(li) in [1, 2]:
                    if not check_num(li):
                        print("输入不合法，请重新输入！")
                    else:
                        if zf:
                            In = "-" + In
                        return In, "num"
                else:
                    print("输入不合法，请重新输入！")
            else:
                if tmp.count("+") > 1 or tmp.count("-") > 2 or tmp.count("*") > 1 or tmp.count("/") > 1:
                    print("输入不合法，请重新输入！")
                else:
                    if tmp.count("+") == 1:
                        li = tmp.split("+")
                        if len(li) == 2 and check_num(li):
                            return In, "exp"
                        else:
                            print("输入的计算式不合法，请重新输入两项计算式！")
                    elif tmp.count("*") == 1:
                        li = tmp.split("*")
                        if len(li) == 2 and check_num(li):
                            return In, "exp"
                        else:
                            print("输入的计算式不合法，请重新输入两项计算式！")
                    elif tmp.count("/") == 1:
                        li = tmp.split("/")
                        if len(li) == 2 and check_num(li):
                            if li[1] != "0":
                                return In, "exp"
                            else:
                                print("输入的计算式不合法，请重新输入两项计算式！")
                        else:
                            print("输入的计算式不合法，请重新输入两项计算式！")
                    elif tmp.count("-") == 1:
                        li = tmp.split("-")
                        if len(li) == 2 and check_num(li):
                            return In, "exp"
                        else:
                            print("输入的计算式不合法，请重新输入两项计算式！")
                    elif tmp.count("-") == 2:
                        li = tmp.split("*", 1)
                        if len(li) == 2 and check_num(li):
                            return In, "exp"
                        else:
                            print("输入的计算式不合法，请重新输入两项计算式！")
                    else:
                        print("输入不合法，请重新输入！")
        else:
            return In, "str"


while True:
    x, t = into("请输入一个数字或者两项计算式：", "num")
    if t == "num":
        while True:
            s, t = into("请输入一个算数运算符（+ - * /）：", "str")
            if t == "str" and (s in ["+", "-", "*", "/"]):
                break
            else:
                print("运算符不合法")
        while True:
            y, t = into("请输入一个数字：", "num")
            if t == "num" and s == "/" and y == "0":
                print("除法的除数不能为零，请重新输入")
            else:
                break

        if s in ["+", "-", "*", "/"]:
            res = eval(x + s + y)
            if type(res) == float:
                if res == 0:
                    res = 0
                else:
                    res = "%.2f" % res
            print("结果为：{} {} {} = {}".format(x, s, y, res))
        else:
            print("运算失败")
    else:
        res = eval(x)
        if type(res) == float:
            if res == 0:
                res = 0
            else:
                res = "%.2f" % res
        print("结果为：{} = {}".format(x, res))
    print("请继续计算下一组(退出请输入q)")
